;Core OS services. It provdies more than 32 services to shell and application
;    Copyleft 2007  Raja Subramanian <raja.email@gmail.com
;
;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;    (at your option) any later version.
;
;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.
;
;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.

OS_INT_SEG      equ     63h*4
OS_INT_OFF      equ     OS_INT_SEG+2
OS_EXIT_PGM_SEG equ     64h*4
OS_EXIT_PGM_OFF equ     OS_EXIT_PGM_SEG+2
OS_INTERRUPT    equ     63h     
SHELL_SEG_ADD   equ     60h

FAT_SEG_ADD     equ     0cee1h ;70h
MEMORY_MAP_SEG  equ     80h

USER_PRG_SEG    equ     100h
USER_DATA_SEG   equ     150H
TSR_PGM_SEG     equ     200H
UDA_SEGMENT     equ     0d5ch ;200h
USER_PROGRAM    equ     0cee1h

CARRAGE_RETURN  equ     0dh
BACK_SPACE      equ     08h
BELL            equ     07h
END_OF_STRING   equ     '$'
END_OF_FILE     equ     1Ah
SPACE           equ     ' '
NULL            equ     255
DELETE_SYMBOL   equ     231
PASSWORD_KEY    equ     23
retry_count     equ     03
code segment
assume cs:code;ds:code;es:nothing
                ORG     100h
BEGIN:          jmp     init

row             db      0
col             db      0
temp            db      0                
temp16          dw      0
cur_retry_count          db      0
current_drive   db      0
source_segment  dw      0
source_offset   dw      0
destination_segment     dw      0
destination_offset      dw      0
buffer          db      512*18 dup (0)
filetype        db      0
sequrity        db      0
pass_offset     dw      0
window_top      db      0
window_bottom   db      24
window_left     db      0
window_right    db      79
window_color    db      07

;find_free_space procedure returns ah=ff->file not found,ah=01->disk full.
;crypt           procedure crypt the password in Ds:Si.
;find_file       procedure returns ah=ff->file not found.
;delay           procedure cx=delay time, wait for some time

init PROC NEAR
                               
                mov ax,3563h
                int 21h
                mov ah,49h
                int 21h

;                mov     ax, offset ivt
;                mov     [0000]:[OS_INT_OFF], ax
;                push    cs
;                pop     ax
;                mov     [0000]:[OS_INT_SEG], ax

                mov     ax, 2563h
                lea     dx, ivt
                int     21h
        
                mov     ax, cs:[2ch]
                mov     es, ax
                mov     ah, 49h
                int     21h

                lea     dx, sizeofcode        
                add     dx, 15                  ; code goes resident
                mov     cl, 04h
                shr     dx, cl
                mov     ax, 3100h               ; Terminate, Stay Resident
                int     21h


init ENDp

ivt PROC NEAR
                cli

                cmp     ah,0            ; Terminate the program
                jnz     next_fn_0
                call    function_0      ; E->NA. ; R->NA.
next_fn_0:

                cmp     ah,1            ; Get the charactor.
                jnz     next_fn_1
                call    function_1      ; E-> Ah=1. ; R->Dl=Ascii code,
                                        ;               Dh=Scan code.
next_fn_1:

                cmp     ah,2            ; Print the charactor on stdout.
                jnz     next_fn_2
                call    function_2      ; E-> Ah=2, Dl=Charactor. ; R->NA.

next_fn_2:

                cmp     ah,3            ;Get a char without echo.
                jnz     next_fn_3
                call    function_3      ; E-> Ah=3. ; R->Dl=Ascii code,
                                        ;               Dh=Scan code.
next_fn_3:

                cmp     ah,4            ; Print the string.
                jnz     next_fn_4
                call    function_4      ; E-> Ah=4 Al=f9h(print in window)
                                        ; Ds:Dx=String. ; R->NA.
next_fn_4:

                cmp     ah,5            ; Get the string.
                jnz     next_fn_5
                call    function_5      ; E-> Ah=5 Ds:Dx=buffer.  
                                        ;       R->Ds:Dx=string,cx=str_len.       
next_fn_5:
                cmp     ah,6            ; Print a char. to printer.
                jnz     next_fn_6
                call    function_6      ; E->Ah=6,Dl=char. ; R->Ax=status.
next_fn_6:

                cmp     ah,7            ; Return OS Version.
                jnz     next_fn_7
                call    function_7      ; E->Ah=7. ; R-> Bh=major version.
                                        ;               Bl=minor version.
next_fn_7:

                cmp     ah,8            ; Get Date(BCD-through CMOS).
                jnz     next_fn_8
                call    function_8      ; E->Ah=8. ; R-> Ch=day, Cl=month
                                        ; Dh=year, Dl=day of the week.
next_fn_8:                      
                cmp     ah,9            ; Set Date(BCD-Sets CMOS CLOCK).
                jnz     next_fn_9
                call    function_9      ; E->Ah=9, Ch=day, Cl=month
                                        ; Dh=year. ;R->Ax=Error code.
next_fn_9:

                cmp     ah,10           ; Get Time(BCD-through CMOS).
                jnz     next_fn_10
                call    function_10     ; E->Ah=10. ; R->Dh=Second,
                                        ; Cl=Miniute, Ch=Hour.
next_fn_10:                             

                cmp     ah,11           ; Set Time(BCD-Sets CMOS CLOCK).
                jnz     next_fn_11
                call    function_11     ; E->Ah=11,Dh=Second,Cl=Miniute,
                                        ; Ch=Hour. ; R->Ax=Error code.
next_fn_11:

                cmp     ah,12           ; Get current drive.
                jnz     next_fn_12
                call    function_12     ; E->Ah=12. ; R -> Al=Drive No.

next_fn_12:

                cmp     ah,13           
                jnz     next_fn_13
                call    function_13     ; E->Ah=13, Al=Drive No.
                                        ; R->Ah=ff(error) or 00(sucess).
next_fn_13:

                cmp     ah,14           ; Read a Sector
                jnz     next_fn_14
                call    function_14     ; E->Ah=14,Es:Bx=buffer,Dx=sector.
                                        ; R->Ax=ffffh if error,
                                        ;    Es:Bx = Sector.
next_fn_14:                             

                cmp     ah,15           ; Write a Sector
                jnz     next_fn_15
                call    function_15     ; E->Ah=15,Es:Bx=buffer,Dx=sector.
                                        ; R->Ax=ffffh if error,
                                        

next_fn_15:

                cmp     ah,16           ; Read Long
                jnz     next_fn_16
                call    function_16     ; E->Ah=16,Es:Bx=buffer,Dx=sector,
                                        ; Cx=number of sector to read.
                                        ; R->Ax=ffffh (error) or 0 (sucess).
                                        ;    Es:Bx = Sector.

next_fn_16:

                cmp     ah,17           ; Write Long
                jnz     next_fn_17
                call    function_17     ; E->Ah=17,Es:Bx=buffer,Dx=sector,
                                        ; Cx=number of sector to Write.
                                        ; R->Ax=ffffh (error) or 0 (sucess).

next_fn_17:

                cmp     ah,18           ; Read one cluster
                jnz     next_fn_18      ; ( 2 cluster = 1 track )
                call    function_18     ; E->Ah=18,Es:Bx=buffer,Dx=Cluster.
                                        ; R->Ax=ffffh (error) or 0 (sucess).
next_fn_18:

                cmp     ah,19           ; Write one cluster
                jnz     next_fn_19
                call    function_19     ; E->Ah=19,Es:Bx=buffer,Dx=Cluster.
                                        ; R->Ax=ffffh (error) or 0 (sucess).
next_fn_19:

                cmp     ah,20           ; Read a File
                jnz     next_fn_20
                call    function_20     ; E->Ah=20,Ds:Dx=File name,
                                        ;          Ds:Si=password,
                                        ;          Es:Bx=buffer.
                                        ; R->Ah=00(sucess),  
                                        ;    Ah=02(file not found),
                                        ;    Ah=01(bad sector).
next_fn_20:                                  

                cmp     ah,21           ; Write to file 
                jnz     next_fn_21
                call    function_21     ; E->Ah=21,Ds:Dx=File name,
                                        ;    Es:Bx=buffer.
                                        ; R->Ah=0(sucess),  
                                        ;    Ah=02(file not found),
                                        ;    Ah=01(bad sector).

next_fn_21:

                cmp     ah,22           ; Create a File.
                jnz     next_fn_22
                call    function_22     ; E->Ah=22,Ds:Dx=file name.
                                        ; Al=file type,Cl=securiry.
                                        ; R->Ah=0(sucess),Ah=01(badsector)
                                        ;    Ah=02(already exist)
next_fn_22:
                cmp     ah,23           ; Delete a File
                jnz     next_fn_23
                call    function_23     ; E->Ah=23,Ds:Dx=file name.
                                        ; Al=File Type, Cl=Security,
                                        ; Es:Bx=Password(not crypted).
                                        ; (Password is needed when Cl=01).
                                        
                                        ; R->Ah=0(sucess),Ah=01(badsector)
                                        ;    Ah=02(unable to delete)
                                        
next_fn_23:

                cmp     ah,24           ; Rename a File
                jnz     next_fn_24
                call    function_24     ; E->Ah=24,Ds:Dx=source file,
                                        ;    Es:Bx=destination file.
                                        ; R->Ah=0(sucess),Ah=01(badsector),
                                        ;    Ah=02(no source file),
                                        ;    Ah=03(duplicate file name).

next_fn_24:

                cmp     ah,25           ; Copy a File
                jnz     next_fn_25
                call    function_25     ; E->Ah=25,Ds:Dx=source file,
                                        ;    Es:Bx=destination file.
                                        ; R->Ah=0(sucess),Ah=01(badsector),
                                        ;    Ah=02(no source file),
                                        ;    Ah=03(duplicate file name).
next_fn_25:

                cmp     ah,26           ; Change File type
                jnz     next_fn_26
                call    function_26     ; E->Ah=25,Ds:Dx=source file,
                                        ;    Cl=New file type.
                                        ; R->Ah=0(sucess),Ah=01(badsector),
                                        ;    Ah=02(no source file),
next_fn_26:


                cmp     ah,27           ; Change Security
                jnz     next_fn_27
                call    function_27     ; E->Ah=25,Ds:Dx=source file,
                                        ;    Ds:Si=password,cl=new securiry.
                                        ;    Ds:Bx=New Password.           
                                        ; R->Ah=0(sucess),Ah=01(badsector),
                                        ;    Ah=02(no source file),
                                        ;    Ah=03(Wrong password).
next_fn_27:

                cmp     ah,28           ; Load and Execute
                jnz     next_fn_28
                call    function_28     ; E->Ah=25,Ds:Dx=source file,
                                        ;    Ds:Si=password.
next_fn_28:

                cmp     ah,29           ; define window
                jnz     next_fn_29
                call    function_29     ; E-> ch,cl,dh,dl=widow coordinates.
next_fn_29:                             ; R-> NA.

                cmp     ah, 30          ; print a charactor through window
                jnz     next_fn_30
                call    function_30     ; E-> Ah=30,Dl=character.; R-> NA.
next_fn_30:

                cmp     ah, 31          ; Get window coordinates
                jnz     next_fn_31
                call    function_31     ; E-> Ah=31,R-> Ch,Cl,Dh,Dl=coor.
next_fn_31:

                cmp     ah, 32          ; change window color
                jnz     next_fn_32
                call    function_32     ; E-> Ah=32,Bh=color.
next_fn_32:


                retf    2
ivt ENDp

function_0 PROC NEAR

                ret
function_0 ENDp

function_1 PROC NEAR

                push    ax
                xor     ax, ax          ; function Zero
                int     16h             ; get a charactor
                mov     dx, ax          ; Save to dx register
                cmp     ah, 0
                jne     function_1_exit ; if key == extended then don't print
                mov     ah, 2           ; else print the key through function One
                int     OS_INTERRUPT    ; to standard output and exit
                pop     ax
function_1_exit:

                ret
function_1 ENDp

function_2 PROC NEAR

                push    ax
                push    bx
                push    cx
                push    dx

                cmp     dl,NULL
                jz      function_2_exit

                cmp     dl, CARRAGE_RETURN
                jne     function_2_conti3

                mov     ah, 3
                mov     bh, 0           
                int     10h             ; get cursor position
                jmp     function_2_conti4

function_2_conti3:
               
                mov     ah, 0ah         ; function 9 to print the char.
                mov     al, dl
                mov     bh, 00          ; set display page
                mov     cx, 1           ; number of times = 1
                int     10h             ; print the character under cursor

                mov     ah, 3
                mov     bh, 0           
                int     10h             ; get cursor position

                cmp     dl, 79                  ;If coloum < 79 then
                jb      function_1_conti1       ;  inc. the cursor position
function_2_conti4:
                cmp     dh, 24                  ;else if row < 24 then
                jbe     function_1_conti2       ;  inc. row and coloum = 0

                push    bx
                push    dx                     ;else
                mov     ax, 0602h
                mov     bh, window_color
                xor     cx, cx
                mov     dx, 2479h               ;  scroll the screen
                int     10h
                pop     dx
                pop     bx                      
                                                ;  and set cursor position
                                                ;    to 24,0 (R,C)
                mov     dh, 23
function_1_conti2:
                inc     dh
                mov     dl, 00h
                mov     ah, 02                  ;set cursor position
                mov     bh, 00
                int     10h
                jmp     function_2_exit
function_1_conti1:
                mov     ah, 02
                mov     bh, 00
                inc     dl
                int     10h
function_2_exit:
                mov     row, dh
                mov     col, dl

                pop     dx
                pop     cx
                pop     bx
                pop     ax

                ret
function_2 ENDp

function_3 PROC NEAR

                push    ax
                xor     ah, ah          
                int     16h             ;Using bios int 16h to a char
                mov     dx,ax           ; and save it in Dx register
                pop     ax
                ret
function_3 ENDp

function_4 PROC NEAR

                push    ax
                push    cx
                push    dx
                push    si

                mov     ah, 02h
                mov     si, dx                   ;Save offset address in Si
                cmp     al, 0f9h
                jnz     function_4_conti

                push    ax
                push    bx
                push    cx
                push    dx

                mov     ah, 3
                mov     bh, 0           
                int     10h             ; get cursor position

                cmp     dh, window_top
                jge     conti1
                mov     dh, window_top
                inc     dh
conti1:
                cmp     dh, window_bottom
                jbe     conti2
                mov     dh, window_bottom
                dec     dh
conti2:
                cmp     dl, window_left
                jge     conti3
                mov     dl, window_left
                inc     dl
conti3:
                cmp     dl, window_right
                jbe     conti4
                mov     dl, window_right
                dec     dl
conti4:
                mov     ah, 2
                mov     bh, 0           
                int     10h             ; set cursor position

                pop     dx
                pop     cx
                pop     bx
                pop     ax

                
                mov     ah, 30
                
function_4_conti:
                mov     dl , byte ptr ds:[si]   
                cmp     dl, END_OF_STRING       ; Is the char. is end of string
                je      function_4_exit         ; yes the exit
                                                ; no, then call print char
                int     OS_INTERRUPT            ; to print the char on stdout
                inc     si                      ; point out to next char
                jmp function_4_conti            ; continue the operation
function_4_exit:
                pop     si                      ; pop all used registers and
                pop     dx
                pop     cx
                pop     ax                      ; return

                ret
function_4 ENDp

function_5 PROC NEAR

                push    ax
                push    bx
                
                push    dx
                push    si
                push    di
                push    ds
                push    es                      ; Save all registers

                mov     si, dx
                mov     di, si                  ; Si = Di = Dx
function_5_conti1:
                xor     ah, ah                  ; Get a char. from 
                int     16h                     ; keyboard buffer

                cmp     al, 0                   ; is it extended key
                jz      function_5_conti1       ; yes then don't bother
                                                
                cmp     al, CARRAGE_RETURN      ; Else if key = ENTER KEY
                jz      function_5_conti2       ; then exit

                cmp     al,BACK_SPACE           ; Is key = BACK SPACE
                jnz     function_5_conti3       ; No then store the char

                cmp     di,si                   ; Is there is any input   
                jge     function_5_conti4       ; no then return
                dec     si                      ; yes then dec. the buffer
                call    backspace               ; and rub the char.
function_5_conti4:
                jmp     function_5_conti1       ; get next char

function_5_conti3:
                mov     bx, di
                add     bx, 80
                cmp     si, bx                  ;check weather buffer is filled
                jle     function_5_conti5       ;no then store

                mov     al,0ffh                 
                out     61h,al
                mov     cx,07
                call    delay
                mov     al,00
                out     61h,al                  ; if yes then beep 
                jmp     function_5_conti1       ; and get next key

function_5_conti5:

                mov     ds:[si],al              ; store the key
                mov     ah, 30
                mov     dl, al
                int     OS_INTERRUPT            ; and print to screen

                inc     si                      ; increment the buffer

                jmp     function_5_conti1       ; and get next key
function_5_conti2:
                mov     al,END_OF_STRING        ; add the terminal symbol
                mov     ds:[si],al              ; to string
                sub     si, di                  ; caculate the lenth of 
                mov     cx, si                  ; string and save in bx
                pop     es
                pop     ds
                pop     di
                pop     si
                pop     dx
                
                pop     bx
                pop     ax
                
                ret
function_5 ENDp

delay PROC NEAR

                push    ax
                push    bx
                push    cx
                push    dx

                push    cx              ; Save delay time
                mov     ah, 00
                int     1ah             ; get timer tick
                add     dl, 07          ; set delay for some micro second
                mov     temp, dl        ; save it 
        
                pop     cx              ; Restore delay time
                cmp     cx, 01
                ja      delay_continue
                add     cs:temp, 7
delay_continue:
                mov     ah, 00
                int     1ah
                cmp     cs:temp, dl
                ja      delay_continue    ; continue the loop untill
                                          ; the time reached
                pop     dx
                pop     cx
                pop     bx
                pop     ax

                ret                       ; restore all register and exit

delay   ENDp

backspace PROC NEAR

                push    ax
                push    bx
                push    cx
                push    dx

                mov     ah, 03
                mov     bh, 00
                int     10h             ;get cursor position

                cmp     dl, 01
                jb      back_one_position

                dec     dl               
                mov     ah,02           
                int     10h             ; decrement the colom position

                mov     al, SPACE       ; and print the space
                mov     ah, 0ah         ; under the cursor position
                mov     cx, 0001
                mov     bh, 00h
                int     10h
back_one_position:
                pop     dx
                pop     cx
                pop     bx
                pop     ax

		ret

backspace ENDp


function_6 PROC NEAR

                push    dx
                

                mov     ah, 00h         ; function 0 (bios interrupt)
                mov     al, dl          ; Al=Ascii character.
                mov     dx, 00h         ; port = Lpt1 (or) PRN.
                int     17h             ; call bios interrupt     

                pop     dx
                ret

function_6 ENDp

function_7 PROC NEAR

                mov     bh, 01          ; Return Major Verision
                mov     bl, 01          ; Return Minor Verision

                ret

function_7 ENDp

function_8 PROC NEAR

                push    ax

                mov     al, 07
                out     70h, al         ; Pointed CMOS RAM  offset 07
                in      al, 71h
                mov     ch, al          ; Read date from offset 07

                mov     al, 08          ; Pointed CMOS RAM  offset 08
                out     70h, al
                in      al, 71h         ; Read month from offset 08
                mov     cl, al

                mov     al, 09          ; Pointed CMOS RAM  offset 09
                out     70h, al
                in      al, 71h         ; Read year from offset 09
                mov     dh, al

                mov     al, 06          ; Pointed CMOS RAM  offset 06
                out     70h, al
                in      al, 71h         ; Read Day of weak from offset 06
                mov     dl, al

                pop     ax
                ret
function_8 ENDp

function_9 PROC NEAR
                push    ax

                mov     al, 07
                out     70h, al         ; Pointed CMOS RAM  offset 07
                mov     al, dh
                out     71h, al         ; Write date to offset 07

                mov     al, 08
                out     70h, al         ; Pointed CMOS RAM  offset 08
                mov     al, dl
                out     71h, al         ; Write month to offset 08

                mov     al, 09
                out     70h, al         ; Pointed CMOS RAM  offset 09
                mov     al, ch
                out     71h, al         ; Write year to offset 09

                pop     ax
                ret
function_9 ENDp

function_10 PROC NEAR

                push    ax

                mov     al, 00
                out     70h, al         ; Pointed CMOS RAM  offset 00
                in      al, 71h         ; Read second from offset 00
                mov     dh, al

                mov     al, 02
                out     70h, al         ; Pointed CMOS RAM  offset 02
                in      al, 71h         ; Read minuute from offset 02
                mov     cl, al

                mov     al, 04
                out     70h, al         ; Pointed CMOS RAM  offset 04
                in      al, 71h         ; Read hour from offset 04
                mov     ch, al

                pop     ax


                ret
function_10 ENDp

function_11 PROC NEAR
                push    ax

                mov     al, 00
                out     70h, al         ; Pointed CMOS RAM  offset 00
                mov     al, dh
                out     71h, al         ; Write second from offset 00

                mov     al, 02
                out     70h, al         ; Pointed CMOS RAM  offset 02
                mov     al, cl
                out     71h, al         ; Write minutes from offset 02

                mov     al, 04
                out     70h, al         ; Pointed CMOS RAM  offset 04
                mov     al, ch
                out     71h, al         ; Write Hour from offset 04

                pop     ax

                ret
function_11 ENDp

function_12 PROC NEAR

                mov     al, current_drive       ; Return current drive

                ret
function_12 ENDp

function_13 PROC NEAR
                
                mov     ah, 0ffh                ; Set error code
                cmp     al, 02
                ja      function_13_exit        ; is it C:
                mov     current_drive, al       ; no the change drive
                mov     ah, 00                  ; clear error code
function_13_exit:
                
                ret
function_13 ENDp

function_14 PROC NEAR
                push    bx
                push    cx
                push    dx
                
                mov     cx, 0001        
                mov     ax, dx                  ; ax = track * 18 + sector.
                or      ax, ax                  ;is track=0 and sector=1
                jz      function_14_conti2      ;yes, then don't divide.


                mov     dl, 18*2        
                div     dl                      ; Ax=Ax/36=>Al=cof.,Ah=rem.
                                                ; (ie)Al=track Ah=sector.
                mov     ch, al                  ; set track..

function_14_conti2:
                mov     dh, 00
                cmp     ah, 18                  ; if sector > 18 then
                jb      function_14_conti1      ;  head=01,sector=sector-18.
                sub     ah, 18                  ; else
                mov     dh, 01                  ;  head = 00.
function_14_conti1:
                mov     cl, ah                  ; Set sector.
                inc     cl                      ; Since sector strats with 1.

                mov     dl, current_drive       ; Set current drive.
                mov     cur_retry_count, 00
function_14_conti3:
                mov     ax, 0201h               ; Read one Sector
                int     13h                     ; at the location Es:Bx.
                jnb     function_14_conti5

                mov     ah, 00
                int     13h

                inc     cur_retry_count
                cmp     cur_retry_count, retry_count
                ja      function_14_conti4      ; Retry the operation 
                jmp     function_14_conti3      ; three times.
function_14_conti4:
                mov     ax,0ffffh
function_14_conti5:
                pop     dx
                pop     cx
                pop     bx

                ret
function_14 ENDp

function_15 PROC NEAR

                push    bx
                push    cx
                push    dx
                

                mov     cx, 0001        
                mov     ax, dx                  ; ax = track * 18 + sector.
                or      ax, ax                  ;is track=0 and sector=1
                jz      function_15_conti2      ;yes, then don't divide.


                mov     dl, 18*2        
                div     dl                      ; Ax=Ax/36=>Al=cof.,Ah=rem.
                                                ; (ie)Al=track Ah=sector.
                mov     ch, al                  ; set track..

function_15_conti2:
                mov     dh, 00
                cmp     ah, 18                  ; if sector > 18 then
                jb      function_15_conti1      ;  head=01,sector=sector-18.
                sub     ah, 18                  ; else
                mov     dh, 01                  ;  head = 00.
function_15_conti1:
                mov     cl, ah                  ; Set sector.
                inc     cl                      ; Since sector strats with 1.

                mov     dl, current_drive       ; Set current drive.
                mov     cur_retry_count, 00
function_15_conti3:
                mov     ax, 0301h               ; Write one Sector
                int     13h                     ; at the location Es:Bx.
                jnb     function_15_conti5

                mov     ah, 00
                int     13h

                inc     cur_retry_count
                cmp     cur_retry_count, retry_count
                ja      function_15_conti4      ; Retry the operation 
                jmp     function_15_conti3      ; three times.
function_15_conti4:
                mov     ax,0ffffh
function_15_conti5:
                
                
                pop     dx
                pop     cx
                pop     bx

                ret

function_15 ENDp

function_16 PROC NEAR

                push    bx
                push    cx
                push    dx                      ;Save all registers
                push    temp16                  ;Assume no errors

                mov     temp16, 0ffffh
function_16_conti1:
                mov     ah,14
                int     OS_INTERRUPT           ;Load first sector
                add     bx,512                 ;increment the buffer
                inc     dx                     ;pointed to next sector

                ;cmp     ax, 0ffffh             ;is any error
                ;jne     function_16_conti2     ;no, then proceed
                ;mov     temp16, 0ffffh         ;yes, then save the error

                cmp     ax, 0ffffh             ;is any error
                je      function_16_conti2     ;no, then proceed

                loop    function_16_conti1     ;read untill cx=0
                mov     temp16, 0h
function_16_conti2:
                mov     ax, temp16             ;set error or sucess code

                pop     temp16
                pop     dx
                pop     cx
                pop     bx                     ; pop all registers and exit
                ret
function_16 ENDp

function_17 PROC NEAR

                push    bx
                push    cx
                push    dx                      ;Save all registers
                push    temp16                  ;Assume no errors
                mov     temp16, 0ffffh
function_17_conti1:
                mov     ah,15
                int     OS_INTERRUPT           ; Write first sector
                add     bx,512                 ; increment the buffer
                inc     dx                     ; pointed to next sector

                ;cmp     ax, 0ffffh             ; is any error
                ;jne     function_17_conti2     ; no, then proceed
                ;mov     temp16, 0ffffh         ; yes, then save the error

                cmp     ax, 0ffffh             ; is any error
                je      function_17_conti2     ; no, then proceed

                loop    function_17_conti1     ; read untill cx=0
                mov     temp16, 0h

function_17_conti2:
                mov     ax, temp16             ; set error or sucess code

                pop     temp16
                pop     dx
                pop     cx
                pop     bx                     ; pop all registers and exit


                ret
function_17 ENDp

function_18 PROC NEAR

                push    bx
                push    cx
                push    dx

                mov     ax, dx                  ; track=Ax=cluster(Dx)*2.
                mov     dl, 18                  ; Original sector=track*18
                mul     dl

                mov     dx, ax                  ; Save the original sec.No.
                xor     cx, cx
                mov     cl, 18

                mov     ah, 16                  ; Fuction 16 to read long
                int     OS_INTERRUPT            ; Call operating system

                pop     dx
                pop     cx
                pop     bx


                ret
function_18 ENDp

function_19 PROC NEAR

                push    bx
                push    cx
                push    dx

                mov     ax, dx                  ; track=Ax=cluster(Dx)*2.
                mov     dl, 18                  ; Original sector=track*18
                mul     dl

                mov     dx, ax                  ; Save the original sec.No.
                xor     cx, cx
                mov     cl, 18

                mov     ah, 17                  ; Fuction 17 to write long
                int     OS_INTERRUPT            ; Call operating system

                pop     dx
                pop     cx
                pop     bx


                ret

                
function_19 ENDp


function_20 PROC NEAR
                
                call    find_file       ; R->Ax=ff(no match),Dx=cluster
                mov     temp, 02        ; Set file not found error
                cmp     ah, 0ffh
                je      function_20_conti1

                push    ax
                push    bx
                push    cx
                push    dx
                push    si
                push    di
                push    es

                xor     ah, ah
                sub     al, 02             ;minor calculations
                mov     dl, 32
                mul     dl                 ;pt. to 70h:free block

                mov     dx, FAT_SEG_ADD
                mov     es, dx
                mov     dx, ax                  ;pointed to FAT

                mov     di, dx
                mov     temp, 00
                cmp     byte ptr es:[di+13], 01 ;Check sequrity byte
                jnz     function_20_conti2

                mov     temp, 04                ;set error flag
                call    crypt                   ;encrypt the password
                mov     cx, 05
                add     di, 16
                cld
                repz    cmpsb                   ;check the password
                
                jnz     function_20_conti2
                mov     temp, 00                ;set flag(correct pass)
function_20_conti2:
                pop     es
                pop     di
                pop     si
                pop     dx
                pop     cx
                pop     bx
                pop     ax
;               call    crypt
                cmp     temp, 00
                jnz     function_20_conti1     
                mov     ah, 18                  ; load the file 
                int     OS_INTERRUPT
                cmp     ax, 0ffffh
                jnz     function_20_conti1
                mov     temp, 01        ; set unable to load
function_20_conti1:
                mov     ah,temp
                
                ret
function_20 ENDp

crypt   PROC NEAR

;This procedure crypt the password in Ds:Si

                push    cx
                push    si
                mov     cx, 10
crypt_next_key:
                xor     byte ptr ds:[si], PASSWORD_KEY
                inc     si
                loop    crypt_next_key
                pop     si
                pop     cx
                ret

crypt   ENDp

load_fat PROC NEAR

                push    bx
                push    cx
                push    dx
                push    es

                mov     ah, 18
                mov     bx, FAT_SEG_ADD ;load FAT to RAM
                mov     es, bx
                xor     bx, bx          ;buffer address = 70h:0
                mov     dx, 01          ;load fat from physical disk
                int     OS_INTERRUPT    ;(fat= head1 sector1-10 track0)

                pop     es
                pop     dx
                pop     cx
                pop     bx

                ret
load_fat ENDp

function_21 PROC NEAR

                call    find_file       ; R->Ax=ff(no match),Dx=cluster
                mov     temp, 02        ; Set file not found error
                cmp     ah, 0ffh
                je      function_21_conti1

                push    ax
                push    bx
                push    cx
                push    dx
                push    si
                push    di
                push    es

                xor     ah, ah
                sub     al, 02             ;minor calculations
                mov     dl, 32
                mul     dl                 ;pt. to 70h:free block

                mov     dx, FAT_SEG_ADD
                mov     es, dx
                mov     dx, ax                  ;pointed to FAT

                mov     di, dx
                mov     temp, 00
                cmp     byte ptr es:[di+13], 01 ;Check sequrity byte
                jnz     function_21_conti2

                mov     temp, 04                ;set error flag
                call    crypt                   ;encrypt the password
                mov     cx, 05
                add     di, 16
                cld
                repz    cmpsb                   ;check the password
                jnz     function_21_conti2
                mov     temp, 00                ;set flag(correct pass)
function_21_conti2:
                pop     es
                pop     di
                pop     si
                pop     dx
                pop     cx
                pop     bx
                pop     ax
                call    crypt                   ;decrypt the password
                cmp     temp, 00
                jnz     function_21_conti1     
                mov     ah, 19                  ; load the file 
                int     OS_INTERRUPT
                cmp     ax, 0ffffh
                jnz     function_21_conti1
                mov     temp, 01        ; set unable to load
function_21_conti1:
                mov     ah,temp
                ret
function_21 ENDp

find_file PROC NEAR
                
                push    bx
                push    cx
                push    si
                push    di
                push    bp
                push    es
                push    temp16

                call    load_fat        ; call subroutine to load fat info.
                mov     bp, 02h         ; initilization(data area starts at
                                        ;    the location 2 cluster)
                mov     si, dx          ; pointed to file name               
                mov     di, FAT_SEG_ADD         
                mov     es, di          ; Pointed to fat segment
                mov     di, 0           ; offset 0
                mov     al, 00h
check_next_file1:
                mov     si, dx          ; pointed to file name               
                mov     cx, 5           ; File name = 10 char. 
                mov     temp16, di      ; Save file block(1block=32byte)
                cld                     ; compare file name in FAT
                repz    cmpsw           ; Ds:Si=file name Es:di=FAT
                jz      file_exist_error    ; jump if file found
                mov     di, temp16      ; load file block (1block=32byte)
                add     di,32           ; pt. to next block(1block=32byte).
                inc     bp              ; increament cluster no.

                mov     ah, es:[di]
                cmp     ah, 00          ; is it end of files
                jz      end_of_free_space   ; yes, then return

                cmp     bp,160          ; is there is any file more
                jb      check_next_file1     ; yes then check next file.
                mov     al, 01          ;Disk full
                jmp     file_exist_error
end_of_free_space:   
                mov     al, 0ffh
file_exist_error:
                mov     ah, al           ; no then return the error code.
                mov     dx, bp          ; Return the cluster number.
                mov     al, dl

                pop     temp16
                pop     es
                pop     bp
                pop     di
                pop     si
                pop     cx
                pop     bx
                ret

find_file ENDp

find_free_space PROC NEAR
                
                push    bx
                push    cx
                push    si
                push    di
                push    bp
                push    es
                push    temp16
                
                mov     bp, 02h         ; initilization(data area starts at
                                        ;    the location 2 cluster)
                
                mov     di, FAT_SEG_ADD         
                mov     es, di          ; Pointed to fat segment
                mov     di, 00          ; offset 0
                mov     al, 00h
check_next_file:
                
                add     di,32           ; pt. to next block(1block=32byte).
                inc     bp              ; increament cluster no.

                mov     ah, es:[di]
                cmp     ah, 00          ; is it end of files
                jz      free_space_found    ; yes, then return

                cmp     ah, DELETE_SYMBOL   ; is it end of files
                jz      free_space_found    ; yes, then return

                cmp     bp,160              ; is there is any file more
                jb      check_next_file     ; yes then check next file.
                mov     al, 01              ;Disk full
                jmp     disk_full
free_space_found:   
                mov     al, 0ffh
disk_full:
                mov     ah, al          ; no then return the error code.
                mov     dx, bp          ; Return the cluster number.
                mov     al, dl

                pop     temp16
                pop     es
                pop     bp
                pop     di
                pop     si
                pop     cx
                pop     bx
                ret

find_free_space ENDp
function_22 PROC NEAR

                ; Create a File.
                push    bx
                push    cx
                push    dx
                push    si
                push    di
                push    es
                push    temp16

                mov     filetype, al
                mov     sequrity, cl
                mov     pass_offset, si

                mov     temp16, dx

                push    ds
                pop     source_segment
                mov     source_offset, dx

                push    es
                pop     destination_segment
                mov     destination_offset, bx 

                mov     cs:temp, 02h
                call    find_file
                cmp     ah, 0ffh           ;is file already exist
                jnz     function_22_conti1 ;yes then exit

                call    find_free_space
                
                mov     cs:temp, 05h

                cmp     ah, 01h           ;is Disk full
                jz      function_22_conti1 ;yes then exit

                xor     ah, ah             
                sub     al, 02             ;minor calculations
                mov     dl, 32
                mul     dl                 ;pt. to 70h:free block

                mov     si, temp16
                mov     di, FAT_SEG_ADD
                mov     es, di
                mov     di, ax
                mov     cx, 05
                cld                        ;write file name in memory area
                repz    movsw

                mov     al, filetype
                mov     byte ptr es:[di],al ;write file type to fat

                inc     di
                mov     ax, 512*18
                mov     word ptr es:[di],ax ;write file size to fat
                inc     di
                inc     di
                mov     cl, sequrity
                mov     byte ptr es:[di],cl ;write file type to fat
                add     di,16-13
                cmp     cl, 01
                jnz     not_a_password

                mov     si, destination_segment
                mov     ds, si
                mov     si, pass_offset
                mov     cl, 05
                cld
                repz    movsw                   ; Save the password
                sub     di,10
                mov     cl, 10
function_22_conti2:
                xor     byte ptr es:[di], PASSWORD_KEY
                inc     di
                loop    function_22_conti2
not_a_password:
                mov     cs:temp, 00h
                xor     bx, bx
                mov     dx, 01
                mov     ah, 19
                int     OS_INTERRUPT       ;write to disk(FAT)
                cmp     ah,0ffh
                jnz     function_22_conti1
                mov     temp, 01h

function_22_conti1:
                mov     ah, cs:temp
                
                pop     temp16
                pop     es
                pop     di
                pop     si
                pop     dx
                pop     cx
                pop     bx
                ret
function_22 ENDp

function_23 PROC NEAR
                ; Delete a File
                push    bx
                push    cx
                push    dx
                push    di
                push    es
                
                call    find_file
                mov     temp, 02h
                cmp     ah, 0ffh           ;if file not found 
                jz      function_23_conti1 ; then exit

                xor     ah, ah             
                sub     al, 2              ;minor calculations
                mov     dl, 32
                mul     dl                 ;pt. to 70h:free block

                mov     di, FAT_SEG_ADD
                mov     es, di
                mov     di, ax
                
                mov     temp, 05                ;set no error flag
                cmp     byte ptr es:[di+13], 00 ;Check sequrity byte
                jz      function_23_conti3      ;  (Normal File).
                mov     temp, 06
                cmp     byte ptr es:[di+13], 01 ;Check sequrity byte
                jnz     function_23_conti1      ;(Password protected).

                push    cx
                push    di
                mov     temp, 04                ;set wrong password flag
                call    crypt                   ;encrypt the password
                mov     cx, 05
                add     di, 16
                cld
                repz    cmpsb                   ;check the password
                jnz     function_23_conti2
                mov     temp, 00                ;set correct password flag

function_23_conti2:
                pop     di
                pop     cx

                call    crypt                   ;decrypt the password
                cmp     temp, 00
                jnz     function_23_conti1     
function_23_conti3:                              

                mov     al, DELETE_SYMBOL  ;replace first charcter  
                mov     es:[di],al         ;this implies file is 
                mov     temp, 00h          ;deleted

                xor     bx, bx
                mov     dx, 01
                mov     ah, 19
                int     OS_INTERRUPT       ;write to disk (FAT)
                cmp     ax,0ffffh
                jnz     function_23_conti1
                mov     temp, 01h

function_23_conti1:
                mov     ah, temp

                pop     es
                pop     di
                pop     dx
                pop     cx
                pop     bx
                ret
                
function_23 ENDp

function_24 PROC NEAR
                ; Rename a File
                push    bx
                push    cx
                push    dx
                push    si
                push    di
                push    es

                push    ds
                pop     source_segment
                mov     source_offset, dx

                push    es
                pop     destination_segment
                mov     destination_offset, bx ;save source and desti.


                push    destination_segment
                pop     ds
                mov     dx, destination_offset
                call    find_file
                mov     temp, 03h
                cmp     ah, 0ffh           ;if file found 
                jnz     function_24_conti1 ; then exit

                push    source_segment
                pop     ds
                mov     dx, source_offset
                call    find_file
                mov     temp, 02h
                cmp     ah, 0ffh           ;if file not found 
                jz      function_24_conti1 ; then exit

                xor     ah, ah
                sub     al, 2              ;minor calculations
                mov     dl, 32
                mul     dl                 ;pt. to 70h:free block

                push    destination_segment
                pop     ds
                mov     si, destination_offset
                mov     di, FAT_SEG_ADD
                mov     es, di
                mov     di, ax
                mov     cx, 05h
                cld
                repz    movsw

                mov     temp, 00h

                xor     bx, bx
                mov     dx, 01
                mov     ah, 19
                int     OS_INTERRUPT       ;write to disk (FAT)
                cmp     ax,0ffffh
                jnz     function_24_conti1
                mov     temp, 01h

function_24_conti1:
                mov     ah, temp
                pop     es
                pop     di
                pop     si
                pop     dx
                pop     cx
                pop     bx

                ret
function_24 ENDp

function_25 PROC NEAR
                ; Copy a File
                push    bx
                push    cx
                push    dx
                push    di
                push    es

                push    ds
                pop     source_segment
                mov     source_offset, dx

                push    es
                pop     destination_segment
                mov     destination_offset, bx ;save source and desti.

                mov     ah, 20
;                mov     bx, UDA_SEGMENT
;                mov     es, bx
;                xor     bx, bx
                push    cs
                pop     es
                mov     bx, offset buffer
                int     OS_INTERRUPT          ;Read source file
                mov     al, 02h
                cmp     ah, 00h
                jnz     function_25_exit

                mov     ah, 22
                push    destination_segment
                pop     ds
                mov     dx, destination_offset
                int     OS_INTERRUPT
                mov     al, 02h
                cmp     ah, 00h
                jnz     function_25_exit


                push    destination_segment
                pop     ds
                mov     dx, destination_offset
                mov     ah, 21
;                mov     bx, UDA_SEGMENT
;                mov     es, bx
;                xor     bx, bx
                push    cs
                pop     es
                mov     bx, offset buffer

                int     OS_INTERRUPT          ;Write to file
                mov     al, 03
                cmp     ah, 00h
                jnz     function_25_exit
                mov     al, 00h

function_25_exit:
                mov     ah, al
                pop     es
                pop     di
                pop     dx
                pop     cx
                pop     bx

                ret
function_25 ENDp

function_26 PROC NEAR
;Change File type
                push    bx
                push    cx
                push    dx
                push    si
                push    di
                push    es

                call    find_file
                mov     temp, 02h
                cmp     ah, 0ffh           ;if file not found 
                jz      function_26_conti1 ; then exit

                xor     ah, ah
                sub     al, 2              ;minor calculations
                mov     dl, 32
                mul     dl                 ;pt. to 70h:free block

                mov     temp, 00h

                mov     di, FAT_SEG_ADD
                mov     es, di
                mov     di, ax
                mov     byte ptr es:[di+10], cl ;Change the file type

                xor     bx, bx
                mov     dx, 01
                mov     ah, 19
                int     OS_INTERRUPT       ; and write to disk (FAT)
                cmp     ah,0ffh
                jnz     function_26_conti1
                mov     temp, 01h

function_26_conti1:
                mov     ah, temp
                pop     es
                pop     di
                pop     si
                pop     dx
                pop     cx
                pop     bx


                ret
function_26 ENDp

function_27 PROC NEAR

                push    bx
                push    cx
                push    dx
                push    di
                push    es
                
                call    find_file
                mov     temp, 02h
                cmp     ah, 0ffh           ;if file not found 
                jz      function_27_conti1 ; then exit

                xor     ah, ah             
                sub     al, 2              ;minor calculations
                mov     dl, 32
                mul     dl                 ;pt. to 70h:free block

                mov     di, FAT_SEG_ADD
                mov     es, di
                mov     di, ax

                mov     temp, 00
                cmp     byte ptr es:[di+13], 01 ;Check sequrity byte
                jnz     function_27_conti3      ;(Password protected).

                push    cx
                push    si
                push    di
                
                mov     temp, 04                ;set wrong password flag
                call    crypt                   ;encrypt the password
                mov     cx, 05
                add     di, 16
                cld
                repz    cmpsb                   ;check the password
                jnz     function_27_conti2
                mov     temp, 00                ;set correct password flag

function_27_conti2:
                pop     di
                pop     si
                pop     cx

                call    crypt                   ;decrypt the password
                cmp     temp, 00
                jnz     function_27_conti1     
function_27_conti3:
                cmp     cl, 01
                jnz     no_need_to_store_password
                push    cx
                push    si
                push    di
                mov     si, bx
                add     di, 16
                ;call    crypt
                mov     cx, 05
                cld
                repz    movsw
                pop     di
                pop     si
                pop     cx
                call    crypt
no_need_to_store_password:
                mov     es:[di+13],cl       ;store security bit
                mov     temp, 00h           ;

                xor     bx, bx
                mov     dx, 01
                mov     ah, 19
                int     OS_INTERRUPT       ;write to disk (FAT)
                cmp     ah,0ffh
                jnz     function_27_conti1
                mov     temp, 01h

function_27_conti1:
                mov     ah, temp

                pop     es
                pop     di
                pop     dx
                pop     cx
                pop     bx
                ret

                ret
function_27 ENDp

function_28 PROC NEAR

                mov     ah, 20
                mov     bx, USER_PROGRAM
                mov     es, bx
                mov     bx, 100h
                int     OS_INTERRUPT            ;Load the program

                push    es
                push    bx
                retf    0002                    ;and give the control.
                
                ret
function_28 ENDp

function_29 PROC NEAR
                push    cx
                push    dx
                inc     ch
                dec     dh
                dec     dh
                inc     cl
                dec     dl
                mov     window_top, ch      
                mov     window_bottom, dh   
                mov     window_left, cl     
                mov     window_right, dl
                pop     dx
                pop     cx
                ret
function_29 ENDp
function_30 PROC NEAR

                push    ax
                push    bx
                push    cx
                push    dx

                cmp     dl,NULL
                jz      function_30_exit

                cmp     dl, CARRAGE_RETURN
                jne     function_30_conti3

                mov     ah, 3
                mov     bh, 0           
                int     10h             ; get cursor position
                jmp     function_30_conti4

function_30_conti3:
               
                mov     ah, 0ah         ; function 9 to print the char.
                mov     al, dl
                mov     bh, 00          ; set display page
                mov     cx, 1           ; number of times = 1
                int     10h             ; print the character under cursor

                mov     ah, 3
                mov     bh, 0           
                int     10h             ; get cursor position

                cmp     dl, window_right        ;If coloum < 79 then
                jb      function_30_conti1       ;  inc. the cursor position
function_30_conti4:
                cmp     dh, window_bottom       ;else if row < 24 then
                jb      function_30_conti2       ;  inc. row and coloum = 0

                push    bx
                push    dx                     ;else
                mov     ax, 0601h
                mov     bh, window_color
                mov     ch, window_top
                mov     cl, window_left
                mov     dh, window_bottom
                mov     dl, window_right
                int     10h
                xor     ah, ah
                int     16h
                pop     dx
                pop     bx                      
                                                ;  and set cursor position
                                                ;    to 24,0 (R,C)
                ;mov     dh, 23
                mov     dh, window_bottom
                dec     dh
function_30_conti2:
                inc     dh
                mov     dl, window_left
                mov     ah, 02                  ;set cursor position
                mov     bh, 00
                int     10h
                jmp     function_30_exit
function_30_conti1:
                mov     ah, 02
                mov     bh, 00
                inc     dl
                int     10h
function_30_exit:
                mov     row, dh
                mov     col, dl

                pop     dx
                pop     cx
                pop     bx
                pop     ax

                ret

function_30 ENDp
function_31 PROC NEAR

                mov     ch, window_top
                mov     dh, window_bottom
                mov     cl, window_left
                mov     dl, window_right
                ret
function_31 ENDp

function_32 PROC NEAR
                mov     window_color, bh
                ret
function_32 ENDp

sizeofcode:
code ENDs

end BEGIN
